﻿using Albatross.WPF.Common;
using Albatross.WPF.Common.ViewModels;
using Albatross.WPF.Common.Views;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace Albatross.Shell.ViewModels {
	public class CloseWorkspacesViewModel : WorkspaceViewModel {
		public class Workspace : ViewModel {
			public Workspace() { Children = new ObservableCollection<Workspace>(); }
			public ObservableCollection<Workspace> Children { get; private set; }

			public WorkspaceViewModel ViewModel { get; set; }
			public FrameworkElement View { get; set; }
			public bool CanClose { get; set; }
			public void Cleanup() {
				foreach (var child in Children) { child.Cleanup(); }
				View.DataContext = null;
				IWorkspaceConstruct construct = (IWorkspaceConstruct)View.GetValue(Attached.WorkspaceConstructProperty);
				if (ViewModel != null && (construct == null || !construct.KeepAlive)) {
					ViewModel.Dispose();
				}
			}
		}

		public ObservableCollection<Workspace> Workspaces { get; private set; }
		public IEnumerable<FrameworkElement> Views{get;private set;}
		public bool RequireConfirmation { get; private set; }
		public bool Confirmed { get; private set; }

		public CloseWorkspacesViewModel(IEnumerable<FrameworkElement> views) {
			Workspaces = new ObservableCollection<Workspace>();
			Views = views;
		}

		public void Seek() {
			HashSet<WorkspaceViewModel> set = new HashSet<WorkspaceViewModel>();
			foreach (var view in Views) {
				FindAllViews(view, Workspaces, set);
			}
		}
		void FindAllViews(FrameworkElement view, ICollection<Workspace> tree, HashSet<WorkspaceViewModel> set) {
			Workspace workspace = null;
			if (view.DataContext is WorkspaceViewModel) {
				WorkspaceViewModel vm = (WorkspaceViewModel)view.DataContext;
				if (!set.Contains(vm)) {
					set.Add(vm);
					IViewService svcs = (IViewService)view.GetValue(Attached.ViewServiceProperty);
					svcs = new AutoViewService(svcs);
					workspace = new Workspace() { ViewModel = vm, CanClose = vm.Closing(svcs), View = view };
					RequireConfirmation = RequireConfirmation || !workspace.CanClose;
					tree.Add(workspace);
				}
			}
			if (workspace != null) {
				tree = workspace.Children;
			}
			foreach (object child in LogicalTreeHelper.GetChildren(view)) {
				if (child is FrameworkElement) {
					FindAllViews((FrameworkElement)child, tree, set);
				}
			}
		}
		public RelayCommand<IViewService> ConfirmCommand { get { return new RelayCommand<IViewService>(Confirm); } }
		void Confirm(IViewService svcs) {
			Confirmed = true;
			svcs.CloseWorkspace(this);
		}
		public void Cleanup() {
			foreach (var item in Workspaces) {
				item.Cleanup();
			}
		}
	}
}
